﻿global using Devonline.AspNetCore;
global using Devonline.Core;
global using Devonline.Database.NoSQL;
global using Devonline.Entity;
global using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

namespace Devonline.Database.MongoDB;

public static class ServiceExtensions
{
    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">MongoDB 数据库配置项</param>
    /// <param name="serviceLifetime">MongoService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddKeyedMongoService(this IServiceCollection services, IMongoEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IMongoEndpoint>(endpoint);
        Func<IServiceProvider, object?, MongoService> implementationFactory = (serviceProvider, _) => new MongoService(serviceProvider.GetRequiredService<ILogger<MongoService>>(), endpoint);
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddKeyedTransient<IMongoService, MongoService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Singleton:
                services.AddKeyedSingleton<IMongoService, MongoService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddKeyedScoped<IMongoService, MongoService>(endpoint.Name, implementationFactory);
                break;
        }

        return services;
    }
    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">MongoDB 数据库配置项</param>
    /// <param name="serviceLifetime">MongoDataService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddKeyedMongoDataService(this IServiceCollection services, IMongoEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IMongoEndpoint>(endpoint);
        Func<IServiceProvider, object?, MongoDataService> implementationFactory = (serviceProvider, _) =>
        {
            var logger = serviceProvider.GetRequiredService<ILogger<MongoDataService>>();
            var httpContextAccessor = serviceProvider.GetRequiredService<IHttpContextAccessor>();
            var httpSetting = serviceProvider.GetRequiredService<HttpSetting>();
            return new MongoDataService(logger, endpoint, httpContextAccessor, httpSetting);
        };
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddKeyedTransient<IMongoDataService, MongoDataService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Singleton:
                services.AddKeyedSingleton<IMongoDataService, MongoDataService>(endpoint.Name, implementationFactory);
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddKeyedScoped<IMongoDataService, MongoDataService>(endpoint.Name, implementationFactory);
                break;
        }

        return services;
    }

    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">MongoDB 数据库配置项</param>
    /// <param name="serviceLifetime">MongoService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddMongoService(this IServiceCollection services, IMongoEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IMongoEndpoint>(endpoint);
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddTransient<IMongoService, MongoService>();
                break;
            case ServiceLifetime.Singleton:
                services.AddSingleton<IMongoService, MongoService>();
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddScoped<IMongoService, MongoService>();
                break;
        }

        return services;
    }
    /// <summary>
    /// 注册数据库上下文
    /// </summary>
    /// <param name="services">依赖注入服务容器</param>
    /// <param name="endpoint">MongoDB 数据库配置项</param>
    /// <param name="serviceLifetime">MongoDataService 生命周期</param>
    /// <returns></returns>
    public static IServiceCollection AddMongoDataService(this IServiceCollection services, IMongoEndpoint endpoint, ServiceLifetime serviceLifetime = ServiceLifetime.Scoped)
    {
        services.AddSingleton<IMongoEndpoint>(endpoint);
        switch (serviceLifetime)
        {
            case ServiceLifetime.Transient:
                services.AddTransient<IMongoDataService, MongoDataService>();
                break;
            case ServiceLifetime.Singleton:
                services.AddSingleton<IMongoDataService, MongoDataService>();
                break;
            case ServiceLifetime.Scoped:
            default:
                services.AddScoped<IMongoDataService, MongoDataService>();
                break;
        }

        return services;
    }
}